package com.tsd.jxc.sale.entity;

import com.tsd.core.constants.Constants;
import com.tsd.core.utils.DoubleUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.jxc.JxcConstants;
import com.tsd.jxc.fin.FinanceConstants;
import com.tsd.jxc.fin.entity.JxcFinanceAccountDetailExt;
import com.tsd.jxc.sale.vo.JxcSaleContractDetailVo;
import com.tsd.jxc.sale.vo.JxcSaleContractVo;
import com.tsd.jxc.stock.StockConstants;
import com.tsd.jxc.stock.entity.JxcStockOutbillExt;
import com.tsd.jxc.stock.entity.JxcStockOutbillItemExt;
import com.tsd.jxc.vo.PrintVo;
import com.tsd.system.entity.SysUserExt;
import com.tsd.utils.AutoInjectUtils;
import io.swagger.annotations.ApiModel;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.tsd.core.constants.Constants.VALUE_NO;
import static com.tsd.core.constants.Constants.VALUE_YES;

/**
 * 销售订单扩展
 *
 * @author Hillpool
 * @date 2022/07/29 15:04:27
 */
@ApiModel(description = "销售订单扩展")
public class JxcSaleOrderExt extends JxcSaleOrder implements Serializable {
    /**
     * 审核拒绝
     */
    public static final int AUDIT_STATE_REJECT = -1;
    /**
     * 未审核
     */
    public static final int AUDIT_STATE_UN_AUDIT = 0;
    /**
     * 已审核
     */
    public static final int AUDIT_STATE_AUDITED = 1;
    /**
     * 是否生成了出库单 0-否
     */
    public static final int OUT_BILL_NO = 0;
    /**
     * 是否生成了出库单 1-部分生成
     */
    public static final int OUT_BILL_SECTION = 1;
    /**
     * 是否生成了出库单 2-全部生成
     */
    public static final int OUT_BILL_ALL = 2;
    /**
     * 是否生成对账 0-否
     */
    public static final int GEN_FINANCE_NO = 0;
    /**
     * 是否生成对账 1-是
     */
    public static final int GEN_FINANCE_YES = 1;

    private List<JxcSaleOrderDetailExt> detail_list;

    private List<Long> id_list;

    private List<String> sid_list;

    private List<String> client_list;

    private String sys_group_name;

    private String client_name;

    private String client_short_name;

    private String client_code;

    private String client_display;

    private String biz_office_name;

    private String office_contract_name;

    private String salesman_name;

    private String auditor_person_name;

    private String goods_code;

    private String goods_name;

    private Integer goods_qty;

    private BigDecimal goods_price;

    private BigDecimal goods_amount;

    private String specifications;

    private Integer goods_return_qty;

    private BigDecimal goods_return_amount;

    private String client_linker_name;

    private String client_linker_mobile;

    private String client_linker_address;

    private String contract_person_name;

    private String contract_person_phone;

    private String client_address;

    public List<JxcSaleOrderDetailExt> getDetail_list() {
        return detail_list;
    }

    public void setDetail_list(List<JxcSaleOrderDetailExt> detail_list) {
        this.detail_list = detail_list;
    }

    public List<Long> getId_list() {
        return id_list;
    }

    public void setId_list(List<Long> id_list) {
        this.id_list = id_list;
    }

    public List<String> getSid_list() {
        return sid_list;
    }

    public void setSid_list(List<String> sid_list) {
        this.sid_list = sid_list;
    }

    public List<String> getClient_list() {
        return client_list;
    }

    public void setClient_list(List<String> client_list) {
        this.client_list = client_list;
    }

    public String getSys_group_name() {
        return sys_group_name;
    }

    public void setSys_group_name(String sys_group_name) {
        this.sys_group_name = sys_group_name;
    }

    public String getClient_name() {
        return client_name;
    }

    public void setClient_name(String client_name) {
        this.client_name = client_name;
    }

    public String getClient_short_name() {
        return client_short_name;
    }

    public void setClient_short_name(String client_short_name) {
        this.client_short_name = client_short_name;
    }

    public String getClient_code() {
        return client_code;
    }

    public void setClient_code(String client_code) {
        this.client_code = client_code;
    }

    public String getClient_display() {
        return client_display;
    }

    public void setClient_display(String client_display) {
        this.client_display = client_display;
    }

    public String getBiz_office_name() {
        return biz_office_name;
    }

    public void setBiz_office_name(String biz_office_name) {
        this.biz_office_name = biz_office_name;
    }

    public String getOffice_contract_name() {
        return office_contract_name;
    }

    public void setOffice_contract_name(String office_contract_name) {
        this.office_contract_name = office_contract_name;
    }

    public String getSalesman_name() {
        return salesman_name;
    }

    public void setSalesman_name(String salesman_name) {
        this.salesman_name = salesman_name;
    }

    public String getAuditor_person_name() {
        return auditor_person_name;
    }

    public void setAuditor_person_name(String auditor_person_name) {
        this.auditor_person_name = auditor_person_name;
    }

    public String getGoods_code() {
        return goods_code;
    }

    public void setGoods_code(String goods_code) {
        this.goods_code = goods_code;
    }

    public String getGoods_name() {
        return goods_name;
    }

    public void setGoods_name(String goods_name) {
        this.goods_name = goods_name;
    }

    public Integer getGoods_qty() {
        return goods_qty;
    }

    public void setGoods_qty(Integer goods_qty) {
        this.goods_qty = goods_qty;
    }

    public BigDecimal getGoods_price() {
        return goods_price;
    }

    public void setGoods_price(BigDecimal goods_price) {
        this.goods_price = goods_price;
    }

    public BigDecimal getGoods_amount() {
        return goods_amount;
    }

    public void setGoods_amount(BigDecimal goods_amount) {
        this.goods_amount = goods_amount;
    }

    public String getSpecifications() {
        return specifications;
    }

    public void setSpecifications(String specifications) {
        this.specifications = specifications;
    }

    public Integer getGoods_return_qty() {
        return goods_return_qty;
    }

    public void setGoods_return_qty(Integer goods_return_qty) {
        this.goods_return_qty = goods_return_qty;
    }

    public BigDecimal getGoods_return_amount() {
        return goods_return_amount;
    }

    public void setGoods_return_amount(BigDecimal goods_return_amount) {
        this.goods_return_amount = goods_return_amount;
    }

    public String getClient_linker_name() {
        return client_linker_name;
    }

    public void setClient_linker_name(String client_linker_name) {
        this.client_linker_name = client_linker_name;
    }

    public String getClient_linker_mobile() {
        return client_linker_mobile;
    }

    public void setClient_linker_mobile(String client_linker_mobile) {
        this.client_linker_mobile = client_linker_mobile;
    }

    public String getClient_linker_address() {
        return client_linker_address;
    }

    public void setClient_linker_address(String client_linker_address) {
        this.client_linker_address = client_linker_address;
    }

    public String getContract_person_name() {
        return contract_person_name;
    }

    public void setContract_person_name(String contract_person_name) {
        this.contract_person_name = contract_person_name;
    }

    public String getContract_person_phone() {
        return contract_person_phone;
    }

    public void setContract_person_phone(String contract_person_phone) {
        this.contract_person_phone = contract_person_phone;
    }

    public String getClient_address() {
        return client_address;
    }

    public void setClient_address(String client_address) {
        this.client_address = client_address;
    }

    public JxcStockOutbillExt genOutBill(String warehouse_sid) {
        JxcStockOutbillExt outBillExt = new JxcStockOutbillExt();
        outBillExt.setWarehouse_sid(warehouse_sid);
        outBillExt.setOut_type(StockConstants.OUT_TYPE_SALE);
        outBillExt.setClient_sid(this.getClient_sid());
        outBillExt.setOut_date(new Date());
        outBillExt.setSrc_sid(this.getSid());
        outBillExt.setSrc_code(this.getCode());
        outBillExt.setExecute_state(Constants.DR_VALID);
        outBillExt.setAudit_state(Constants.DR_VALID);
        List<JxcSaleOrderDetailExt> detailExtList = ListUtil.filter(this.getDetail_list(), t -> !StockConstants.DETAIL_IN_OUT_BILL_ALL.equals(t.getOut_bill()));
        List<JxcStockOutbillItemExt> itemExtList = ListUtil.map(detailExtList, JxcSaleOrderDetailExt::genOutBillItem);
        outBillExt.setItem_list(itemExtList);
        return outBillExt;
    }

    public JxcSaleReturnBillExt genReturnBill() {
        JxcSaleReturnBillExt returnBillExt = new JxcSaleReturnBillExt();
        returnBillExt.setReturn_date(new Date());
        returnBillExt.setSale_order_sid(this.getSid());
        returnBillExt.setClient_sid(this.getClient_sid());
        returnBillExt.setClient_name(this.getClient_name());
        returnBillExt.setClient_code(this.getClient_code());
        returnBillExt.setClient_short_name(this.getClient_short_name());
        returnBillExt.setIn_bill(Constants.DR_VALID);
        List<JxcSaleReturnBillDetailExt> detailExtList = ListUtil.map(this.getDetail_list(), JxcSaleOrderDetailExt::genReturnBillDetail);
        detailExtList = ListUtil.filter(detailExtList, t -> !HlpUtils.isEmpty(t.getQty()) && t.getQty().doubleValue() > 0);
        double totalQty = 0D, totalAmount = 0D;
        for (JxcSaleReturnBillDetailExt detailExt : detailExtList) {
            detailExt.setSale_order_code(this.getCode());
            totalQty = DoubleUtil.add(totalQty, detailExt.getQty());
            totalAmount = DoubleUtil.add(totalAmount, detailExt.getAmount());
        }
        returnBillExt.setQty(BigDecimal.valueOf(totalQty));
        returnBillExt.setAmount(BigDecimal.valueOf(totalAmount));
        returnBillExt.setDetail_list(detailExtList);
        return returnBillExt;
    }

    /**
     * 根据销售订单生成对账单
     * 先生成应收金额的对账单
     * 再生成抹零金额的对账单
     *
     * @return
     */
    public List<JxcFinanceAccountDetailExt> genAccountDetail() {
        List<JxcFinanceAccountDetailExt> list = new ArrayList<>();
        JxcFinanceAccountDetailExt detailExt = new JxcFinanceAccountDetailExt();
        detailExt.setType(FinanceConstants.TYPE_RECEIVABLE);
        detailExt.setBill_type(FinanceConstants.BILL_TYPE_SALE_ORDER);
        detailExt.setRelated_party_sid(this.getClient_sid());
        detailExt.setThe_date(new Date());
        detailExt.setReceivable_amount(this.getTotal_amount());
        detailExt.setRelation_sid(this.getSid());
        detailExt.setRelation_code(this.getCode());
        list.add(detailExt);
        if (!HlpUtils.isEmpty(this.getIgnore_amount()) && this.getIgnore_amount().doubleValue() > 0) {
            JxcFinanceAccountDetailExt ignoreDetailExt = new JxcFinanceAccountDetailExt();
            ignoreDetailExt.setType(FinanceConstants.TYPE_RECEIVABLE);
            ignoreDetailExt.setBill_type(FinanceConstants.BILL_TYPE_SALE_ORDER_IGNORE);
            ignoreDetailExt.setRelated_party_sid(this.getClient_sid());
            ignoreDetailExt.setThe_date(new Date());
            ignoreDetailExt.setReceivable_amount(this.getIgnore_amount());
            ignoreDetailExt.setRelation_sid(this.getSid());
            ignoreDetailExt.setRelation_code(this.getCode());
            list.add(ignoreDetailExt);
        }
        return list;
    }

    public PrintVo convert2Print(SysUserExt userExt) {
        PrintVo vo = new PrintVo();
        vo.setCode(this.getCode());
        vo.setCreator_name(this.getCreator_name());
        vo.setCreate_date(this.getCreate_date());
        vo.setAuditor_name(this.getAuditor_name());
        vo.setAudit_date(this.getAudit_date());
        vo.setOrder_date(this.getOrder_date());
        vo.setClient_order_code(this.getClient_order_code());
        vo.setClient_display(this.getClient_display());
        vo.setClient_linker_name(this.getClient_linker_name());
        vo.setClient_linker_mobile(this.getClient_linker_mobile());
        vo.setClient_linker_address(this.getClient_linker_address());
        vo.setBiz_office_name(this.getBiz_office_name());
        vo.setOffice_contract_name(this.getOffice_contract_name());
        vo.setQty(this.getQty());
        vo.setAmount(this.getAmount());
        vo.setPre_freight(this.getPre_freight());
        vo.setReal_freight(this.getReal_freight());
        vo.setFree_shipping(this.getFree_shipping());
        vo.setTotal_amount(this.getTotal_amount());
        vo.setIgnore_amount(this.getIgnore_amount());
        vo.setShould_receive_amount(this.getShould_receive_amount());
        vo.setReceived_amount(this.getReceived_amount());
        vo.setUn_receive_amount(this.getUn_receive_amount());
        vo.setClient_req_delivery_date(this.getClient_req_delivery_date());
        vo.setClient_req_receive_date(this.getClient_req_receive_date());
        vo.setDelivery_mode(this.getDelivery_mode());
        vo.setSalesman_name(this.getSalesman_name());
        vo.setState(this.getState());
        vo.setReturn_qty(this.getReturn_qty());
        vo.setReturn_amount(this.getReturn_amount());
        vo.setNote_info(this.getNote_info());
        vo.setOut_bill(this.getOut_bill());
        vo.setGen_finance(this.getGen_finance());
        List<PrintVo> detailList = ListUtil.map(this.getDetail_list(), JxcSaleOrderDetailExt::convert2Print);
        vo.setDetail_list(detailList);
        if (userExt != null) {
            vo.setPrint_name(userExt.getName());
        }
        vo.setPrint_datetime(new Date());
        return vo;
    }

    public JxcSaleOrderExt copy() {
        JxcSaleOrderExt orderExt = new JxcSaleOrderExt();
        orderExt.setId(this.getId());
        orderExt.setSid(this.getSid());
        orderExt.setOrder_date(this.getOrder_date());
        orderExt.setClient_sid(this.getClient_sid());
        orderExt.setBiz_office_sid(this.getBiz_office_sid());
        orderExt.setBiz_office_contract_name(this.getBiz_office_contract_name());
        orderExt.setClient_name(this.getClient_name());
        orderExt.setClient_code(this.getClient_code());
        orderExt.setClient_short_name(this.getClient_short_name());
        return orderExt;
    }

    public String getSpec_name() {
        return null;
    }

    public String getAudit_state_name() {
        if (!HlpUtils.isEmpty(this.getState())) {
            if (this.getAudit_state() == AUDIT_STATE_UN_AUDIT) {
                return "待审核";
            } else if (this.getAudit_state() == AUDIT_STATE_AUDITED) {
                return "已审核";
            } else if (this.getAudit_state() == AUDIT_STATE_REJECT) {
                return "已拒绝";
            }
        }
        return null;
    }

    public String getState_name() {
        if (!HlpUtils.isEmpty(this.getState())) {
            if (this.getState() == VALUE_YES) {
                return "有效";
            } else if (this.getState() == VALUE_NO) {
                return "已作废";
            }
        }
        return null;
    }

    public String getOut_bill_name() {
        if (!HlpUtils.isEmpty(this.getOut_bill())) {
            if (this.getOut_bill() == OUT_BILL_NO) {
                return "否";
            } else if (this.getOut_bill() == OUT_BILL_SECTION) {
                return "部分生成";
            } else if (this.getOut_bill() == OUT_BILL_ALL) {
                return "全部生成";
            }
        }
        return null;
    }

    public String getGen_finance_name() {
        if (!HlpUtils.isEmpty(this.getGen_finance())) {
            if (this.getGen_finance() == GEN_FINANCE_NO) {
                return "否";
            } else if (this.getGen_finance() == GEN_FINANCE_YES) {
                return "是";
            }
        }
        return null;
    }

    public String getInvoice_info() {
        if (!HlpUtils.isEmpty(this.getInvoice_type())) {
            if (this.getInvoice_type() == JxcConstants.INVOICE_TYPE_NO_NEED) {
                return "不需要发票";
            }
            if (this.getInvoice_type() == JxcConstants.INVOICE_TYPE_DZFP) {
                if (JxcConstants.INVOICE_STATE_WAIT == this.getInvoice_state()) {
                    return "待申请【普】";
                }
                if (JxcConstants.INVOICE_STATE_DOING == this.getInvoice_state()) {
                    return "已申请【普】";
                }
                return "已开普票";
            }
            if (this.getInvoice_type() == JxcConstants.INVOICE_TYPE_ZYFP) {
                if (JxcConstants.INVOICE_STATE_WAIT == this.getInvoice_state()) {
                    return "待申请【专】";
                }
                if (JxcConstants.INVOICE_STATE_DOING == this.getInvoice_state()) {
                    return "已申请【专】";
                }
                return "已开专票";
            }
        }
        return null;
    }

    public JxcSaleContractVo convert2ContractVo() {
        JxcSaleContractVo contractVo = new JxcSaleContractVo();
        contractVo.setContract_code(this.getContract_code());
        contractVo.setClient_name(this.getClient_name());
        contractVo.setClient_address(this.getClient_linker_address());
        contractVo.setClient_linker_name(this.getClient_linker_name());
        contractVo.setClient_linker_phone(this.getClient_linker_mobile());
        contractVo.setInclude_tax_str(JxcConstants.INVOICE_TYPE_NO_NEED == this.getInvoice_type() ? "不含税" : "含税");
        List<JxcSaleContractDetailVo> detailVoList = ListUtil.map(this.getDetail_list(), JxcSaleOrderDetailExt::convert2ContractDetailVo);
        double totalAmount = 0D;
        int index = 1;
        for (JxcSaleContractDetailVo detailVo : detailVoList) {
            detailVo.set_index(index);
            totalAmount = DoubleUtil.add(totalAmount, detailVo.getTotal_amount());
            index += 1;
        }
        contractVo.setDetail_list(detailVoList);
        contractVo.setTotal_amount(BigDecimal.valueOf(totalAmount));
        contractVo.setDelivery_date(this.getPre_delivery_date());
        contractVo.setThe_date(new Date());
        return contractVo;
    }

    public void clearData4Copy() {
        AutoInjectUtils.clearBaseData(this);
        this.setCode(null);
        this.setOrder_date(new Date());
        this.setReceived_amount(null);
        this.setInvoice_state(0);
        this.setInvoice_amount(null);
        this.setPay_req_state(0);
        this.setTax_amount(null);
        this.setCut_amount(null);
        this.setSend_qty(null);
        List<JxcSaleOrderDetailExt> detailExtList = this.getDetail_list();
        if (!HlpUtils.isEmptyList(detailExtList)) {
            for (JxcSaleOrderDetailExt detailExt : detailExtList) {
                AutoInjectUtils.clearBaseData(detailExt);
                detailExt.setPay_req_state(null);
            }
        }
        this.setDetail_list(detailExtList);
    }
}
